home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / pointers.swg / 0038_Ordered List Unit with Key.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-08-30  |  8.8 KB  |  273 lines

  1. unit OrdLists;
  2.  
  3. {--------------------------------------------------------------------------}
  4. { Abstract Data Type for a key ordered list.                               }
  5. { By Michael Dales 30th May 1996                                           }
  6. {                                                                          }
  7. { A simple ordered list ADT. All you need to use are the decalred          }
  8. { methods below, you don't even need to know how the type works either.    }
  9. { To use the list just assign the list variable the type TOrdList, and     }
  10. { rember to use CreateList before you try and do any operations on it. The }
  11. { data in each node is stored as a pointer, and each node has a key by     }
  12. { which the list is ordered which is a 32 character array, type called     }
  13. { TKey. The type of each node is called PListNode.                         }
  14. {                                                                          }
  15. { I've designed this as an abstract data type, which means that although   }
  16. { you can look at the code and see how I've implemented it, you can (and   }
  17. { should) use just the methods I've declared in the interface of this      }
  18. { unit. Hence the word abstract in abstract data type. So there.           }
  19. {                                                                          }
  20. { If you have any comments the email me at: 9402198d@udcf.gla.ac.uk        }
  21. { URL: http://www.gla.ac.uk/Clubs/WebSoc/~9402198d/index.html              }
  22. {--------------------------------------------------------------------------}
  23.  
  24. interface
  25.  
  26. uses Strings;
  27.  
  28. const null = nil;        {Non specific terminator}
  29.  
  30. type TKey      = array[0..32] of char;
  31.  
  32.      PListNode = ^TListNode;             {Pointer to node}
  33.      TListNode = record                  {Node record}
  34.                Key       : TKey;         {Key for node}
  35.                Item      : Pointer;      {Pointer to node data}
  36.                Next      : PListNode;    {Next node}
  37.                Previous  : PListNode;    {Previous node}
  38.      end;
  39.  
  40.      TOrdList = record                {Holder for list}
  41.            First : PListNode;         {Pointer to start of list}
  42.            Rear  : PListNode;         {Pointer to end of list}
  43.            Size  : integer;           {Size of list}
  44.      end;
  45.  
  46. {CreateList - Initiates a new list}
  47. procedure CreateList(var L : TOrdList);
  48.  
  49. {DestroyList - Frees up all memory used by list and sets list to nil}
  50. procedure DestroyList(var L : TOrdList);
  51.  
  52. {AddNewNode - Adds new node to list L, filling it with the data
  53.               supplied. Returns true is new node sucessfully
  54.               added, otherwise returns false.}
  55. procedure AddNewNode(var L : TOrdList; AKey : PChar; Data : Pointer);
  56.  
  57. {DeleteNode - Deletes an element passed.}
  58. procedure DeleteNode(var L : TOrdList; ANode : PListNode);
  59.  
  60. {GetFirstNode - Returns the first node in a given list}
  61. function GetFirstNode(L : TOrdList) : PListNode;
  62.  
  63. {FindFirstNode - Finds the first node with a matching key}
  64. function FindFirstNode(L : TOrdList; AKey : TKey) : PListNode;
  65.  
  66. {GetNextNode - Returns the successor of the given node}
  67. function GetNextNode(Node : PListNode) : PListNode;
  68.  
  69. {GetNodeData - Returns the data in a specific node}
  70. procedure GetNodeData(Node : PListNode; var Data : Pointer);
  71.  
  72. {GetNodeKey - Returns the key for a given node}
  73. procedure GetNodeKey(Node : PListNode; var AKey : TKey);
  74.  
  75. {UpdateNode - Replaces a nodes details with new ones}
  76. procedure UpdateNode(Node : PListNode; Data : Pointer);
  77.  
  78. {--------------------------------------------------------------------------}
  79. implementation
  80. {--------------------------------------------------------------------------}
  81.  
  82.     {CreateList - Initiates a new list}
  83.  
  84. procedure CreateList(var L : TOrdList);
  85. begin
  86.      L.First := nil;      {No list yet}
  87.      L.Rear := nil;
  88.      L.Size := 0;         {No length yet}
  89. end;
  90.  
  91.  
  92.     {RemoveLastNode - Deletes last node on the list}
  93.  
  94. procedure RemoveLastNode(var L : TOrdList);
  95. begin
  96.      with L do                                  {With the list}
  97.      begin
  98.           if Size > 0 then                        {If nodes in list}
  99.           begin
  100.                if Size = 1 then                   {If just one node}
  101.                begin
  102.                     if First^.Item <> nil then  {If data in node then}
  103.                        Dispose(First^.Item);        {Dispose of it}
  104.                     Dispose(First);             {Dispose of first node}
  105.                     First := nil;
  106.                     Rear := nil;                  {Set rear to nil}
  107.                end else
  108.                begin                            {If more than one node}
  109.                     if Rear^.Item <> nil then
  110.                        Dispose(Rear^.Item);
  111.                     Rear := Rear^.Previous;       {Set rear to second last}
  112.                     Dispose(Rear^.Next);        {Remove last node}
  113.                end;
  114.                Size := Size-1;                    {Decrement list size}
  115.           end;
  116.      end;
  117. end;
  118.  
  119.  
  120.     {DestroyList - Frees up all memory used by list and sets list to nil}
  121.  
  122. procedure DestroyList(var L : TOrdList);
  123. begin
  124.      while L.First <> nil do              {While still nodes left}
  125.            RemoveLastNode(L);             {Remove last node}
  126.      CreateList(L);
  127. end;
  128.  
  129.  
  130.     {GetFirstNode - Returns the first node in a given list}
  131.  
  132. function GetFirstNode(L : TOrdList) : PListNode;
  133. begin
  134.      GetFirstNode := L.First;
  135. end;
  136.  
  137.  
  138.     {FindFirstNode - Finds the first node with a matching key}
  139.  
  140. function FindFirstNode(L : TOrdList; AKey : TKey) : PListNode;
  141. var temp  : PListNode;
  142.     found : boolean;
  143. begin
  144.      found := false;
  145.      temp := L.First;
  146.      while (temp <> nil) and not found do
  147.      begin
  148.           found := temp^.Key = AKey;
  149.           if not found then temp := temp^.Next;
  150.      end;
  151.      FIndFirstNode := temp;
  152. end;
  153.  
  154.  
  155.     {GetNextNode - Returns the successor of the given node}
  156.  
  157. function GetNextNode(Node : PListNode) : PListNode;
  158. begin
  159.      if Node <> nil then
  160.         GetNextNode := Node^.Next
  161.      else
  162.          GetNextNode := nil;
  163. end;
  164.  
  165.  
  166.     {GetNodeData - Returns the data in a specific node}
  167.  
  168. procedure GetNodeData(Node : PListNode; var Data : Pointer);
  169. begin
  170.      if Node <> nil then
  171.         Data := Node^.Item
  172.      else
  173.          Data := nil;
  174. end;
  175.  
  176.  
  177.     {GetNodeKey - Returns the key for a given node}
  178.  
  179. procedure GetNodeKey(Node : PListNode; var AKey : TKey);
  180. begin
  181.      if node <> nil then
  182.         AKey := Node^.Key;
  183. end;
  184.  
  185.  
  186.     {AddNewNode - Adds new node to list L, filling it with the data
  187.                   supplied. Returns true is new node sucessfully
  188.                   added, otherwise returns false.}
  189.  
  190. procedure AddNewNode(var L : TOrdList; AKey : PChar; Data : Pointer);
  191. var temp    : PListNode;
  192.     CurNode : PListNode;
  193.     Match   : boolean;
  194. begin
  195.      new(temp);                 {Create new node}
  196.      with temp^ do              {Fill node}
  197.      begin
  198.           StrCopy(Key, AKey);
  199.           Item := Data;
  200.           Next := nil;
  201.           Previous := nil;
  202.      end;
  203.      if L.Size = 0 then
  204.      begin
  205.           L.First := temp;
  206.           L.Rear := temp;
  207.      end else
  208.      begin
  209.           CurNode := L.First;
  210.           Match := false;
  211.           while (CurNode <> nil) and not Match do
  212.           begin
  213.                if StrComp(CurNode^.Key, AKey) >= 0 then
  214.                   Match := true
  215.                else
  216.                    CurNode := CurNode^.Next;
  217.           end;
  218.           if not Match then
  219.           begin
  220.                temp^.Previous := L.Rear;
  221.                L.Rear^.Next := temp;
  222.                L.Rear := temp;
  223.           end else
  224.           begin
  225.                temp^.Next := CurNode;
  226.                temp^.Previous := CurNode^.Previous;
  227.                if (CurNode^.Previous <> nil) then
  228.                   CurNode^.Previous^.Next := temp
  229.                else
  230.                    L.First := temp;
  231.                CurNode^.Previous := temp;
  232.           end;
  233.      end;
  234.      L.Size := L.Size + 1;          {Increment list length}
  235. end;
  236.  
  237.  
  238.     {UpdateNode - Replaces a nodes details with new ones}
  239.  
  240. procedure UpdateNode(Node : PListNode; Data : Pointer);
  241. begin
  242.      if Node <> nil then
  243.      begin
  244.           Node^.Item := Data;
  245.      end;
  246. end;
  247.  
  248.  
  249.     {DeleteNode - Deletes an element passed.}
  250.  
  251. procedure DeleteNode(var L : TOrdList; ANode : PListNode);
  252. begin
  253.      if (L.Size = 1) or (ANode^.Next = nil) then
  254.         RemoveLastNode(L)
  255.      else
  256.      begin
  257.           if (ANode = L.First) then
  258.           begin
  259.                L.First := L.First^.Next;
  260.                L.First^.Previous := nil;
  261.                Dispose(ANode);
  262.           end else
  263.           begin
  264.                ANode^.Previous^.Next := ANode^.next;
  265.                ANode^.Next^.Previous := ANode^.Previous;
  266.                Dispose(ANode);
  267.           end;
  268.           L.Size := L.Size-1;
  269.      end;
  270. end;
  271.  
  272. end.
  273.